package JDK常用类库.stream;

//import lombok.Data;
import org.junit.Test;

import java.util.*;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author zx
 * @create 2023-08-06 22:31
 * 1.Stream关注的是对数据的运算，与CPU打交道
 *   集合关注的是数据的存储，与内存打交道
 * 2.
 *   Stream自己不会存储元素
 *   Stream不会改变源对象，相反，他们会返回一个持有结果的新Stream
 *   Stream操作是延迟执行的。意味着他们会等到需要结果的时候才执行
 * 3.Stream执行流程
 *   Stream的实例化
 *   一系列的中间操作(过滤、映射)
 *   终止操作
 * 4.说明：
 *   4.1 一个中间操作链，对数据源的数据进行处理
 *   4.2 一旦执行终止操作，就执行中间操作链，并产生结果。之后，不会再被使用
 */
public class StreamAPITest {
    /**
     * 创建方式一：通过集合
     */
    @Test
    public void test1(){
        /**
         * 根据Collection获取
         */
        List<Employee> employees = EmployeeData.getEmployees();
        //default Stream<E> stream(): 创建一个顺序流
        Stream<Employee> stream = employees.stream();
        //default Stream<E> parallelStream(): 创建一个并行流
        Stream<Employee> parallelStream = employees.parallelStream();

        /**
         * Map接口别没有实现Collection接口, 可以根据Map获取对应的key value的集合
         */
        Map<String,Object> map = new HashMap<>();
        Stream<String> stream1 = map.keySet().stream();
        Stream<Object> stream2 = map.values().stream();
        Stream<Map.Entry<String, Object>> stream3 = map.entrySet().stream();
    }

    /**
     * 创建Stream方式二：通过数组
     */
    @Test
    public void test2(){
        int[] arr = new int[]{1,2,3,4,5,6};
        IntStream stream = Arrays.stream(arr);
    }

    /**
     * 创建Stream方式三：通过Stream的of()
     */
    @Test
    public void test3(){
        Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
    }

    /**
     * 创建Stream方式四：由函数创建流，创建无限流(用的比较少，了解即可)
     */
    @Test
    public void test4(){
        //迭代：使用 iterate()：根据指定的初始值和 UnaryOperator 生成一个无限长度的 Stream。
        Stream.iterate(0, t -> t - 2).limit(10).forEach(System.out::println);
        //生成：使用 generate()：根据指定的 Supplier 生成一个无限长度的 Stream
        Stream.generate(() -> new Random().nextInt(100))
                .limit(5)
                .forEach(System.out::println);
        Stream.generate(Math::random).limit(10).forEach(System.out::println);
    }
}

class EmployeeData{
    public static List<Employee> getEmployees(){
        List<Employee> list = new ArrayList<>();
        list.add(new Employee(1001,"马化腾",34,10000));
        list.add(new Employee(1002,"马腾",35,12000));
        list.add(new Employee(1003,"马",36,14000));
        list.add(new Employee(1004,"化",37,16000));
        list.add(new Employee(1005,"腾",38,18000));
        return list;
    }
}

//@Data
class Employee{
    private int id;
    private String name;
    private int age;
    private double salary;

    public Employee(int id, String name, int age, double salary){
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }
}